package cn.stylefeng.guns.modular.gridsystem.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.guns.core.exception.ServiceException;
import cn.stylefeng.guns.core.exception.enums.StatusExceptionEnum;
import cn.stylefeng.guns.core.factory.PageFactory;
import cn.stylefeng.guns.core.pojo.page.PageResult;
import cn.stylefeng.guns.modular.gridsystem.entity.BizGatewayConfigTemplate;
import cn.stylefeng.guns.modular.gridsystem.mapper.BizGatewayConfigTemplateMapper;
import cn.stylefeng.guns.modular.gridsystem.model.param.BizGatewayConfigTemplateParam;
import cn.stylefeng.guns.modular.gridsystem.model.param.DirectoryTreeParam;
import cn.stylefeng.guns.modular.gridsystem.service.BizGatewayConfigTemplateService;
import cn.stylefeng.guns.sys.modular.dict.param.SysDictTypeParam;
import cn.stylefeng.guns.sys.modular.dict.service.SysDictTypeService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 网关配置模板 服务实现类
 *
 * @author ssy
 * @date 2022/10/31 15:31
 */
@Service
@RequiredArgsConstructor
public class BizGatewayConfigTemplateServiceImpl extends ServiceImpl<BizGatewayConfigTemplateMapper, BizGatewayConfigTemplate> implements BizGatewayConfigTemplateService {


    @Resource
    private SysDictTypeService sysDictTypeService;

    /**
     * 分页查询网关配置模板
     *
     * @param param
     * @return
     */
    @Override
    public PageResult<BizGatewayConfigTemplate> page(BizGatewayConfigTemplateParam param) {
        // 构造条件
        LambdaQueryWrapper<BizGatewayConfigTemplate> queryWrapper = new LambdaQueryWrapper<>();
        // 名称模糊匹配
        queryWrapper.like(ObjectUtil.isNotEmpty(param.getConfigName()), BizGatewayConfigTemplate::getConfigName, param.getConfigName())
                // 类型模糊匹配
                .like(ObjectUtil.isNotEmpty(param.getCode()), BizGatewayConfigTemplate::getCode, param.getCode())
                // 排序
                .orderByDesc(BizGatewayConfigTemplate::getCreateTime);
        return new PageResult<>(this.page(PageFactory.defaultPage(), queryWrapper));
    }

    /**
     * 查询所有网关配置模板
     *
     * @param bizGatewayConfigTemplateParam
     * @return
     */
    @Override
    public List<BizGatewayConfigTemplate> list(BizGatewayConfigTemplateParam bizGatewayConfigTemplateParam) {
        // 构造条件
        LambdaQueryWrapper<BizGatewayConfigTemplate> queryWrapper = new LambdaQueryWrapper<>();
        if (bizGatewayConfigTemplateParam != null && ObjectUtil.isNotEmpty(bizGatewayConfigTemplateParam.getGatewayConfigCode())) {
            queryWrapper.eq(BizGatewayConfigTemplate::getGatewayConfigCode, bizGatewayConfigTemplateParam.getGatewayConfigCode());
        }
        return this.list(queryWrapper);
    }

    /**
     * 添加网关配置模板
     *
     * @param bizGatewayConfigTemplateParam
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(BizGatewayConfigTemplateParam bizGatewayConfigTemplateParam) {
        // 校验参数，检查是否存在重复的编码或者名称，不排除当前添加的这条记录
        checkParam(bizGatewayConfigTemplateParam, false);
        // 将dto转为实体
        BizGatewayConfigTemplate bizGatewayConfigTemplate = BizGatewayConfigTemplate.builder().build();
        BeanUtil.copyProperties(bizGatewayConfigTemplateParam, bizGatewayConfigTemplate);
        this.save(bizGatewayConfigTemplate);
    }

    /**
     * 删除网关配置模板
     *
     * @param bizGatewayConfigTemplateParam
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(BizGatewayConfigTemplateParam bizGatewayConfigTemplateParam) {
        this.removeById(bizGatewayConfigTemplateParam.getId());
    }

    /**
     * 编辑网关配置模板
     *
     * @param bizGatewayConfigTemplateParam
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(BizGatewayConfigTemplateParam bizGatewayConfigTemplateParam) {
        // 根据id查询实体
        BizGatewayConfigTemplate bizGatewayConfigTemplate = this.queryBizGatewayConfigTemplate(bizGatewayConfigTemplateParam);
        // 校验参数，检查是否存在重复的编码或者名称，排除当前编辑的这条记录
        checkParam(bizGatewayConfigTemplateParam, true);
        // 请求参数转化为实体
        BeanUtil.copyProperties(bizGatewayConfigTemplateParam, bizGatewayConfigTemplate);
        // 不能修改状态，用修改状态接口修改状态
        bizGatewayConfigTemplate.setStatus(null);
        this.updateById(bizGatewayConfigTemplate);
    }

    /**
     * 查看详情网关配置模板
     *
     * @param bizGatewayConfigTemplateParam
     * @return
     */
    @Override
    public BizGatewayConfigTemplate detail(BizGatewayConfigTemplateParam bizGatewayConfigTemplateParam) {
        return this.queryBizGatewayConfigTemplate(bizGatewayConfigTemplateParam);
    }

    /**
     * 修改状态（字典 0正常 1停用 2删除）
     *
     * @param bizGatewayConfigTemplateParam
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeStatus(BizGatewayConfigTemplateParam bizGatewayConfigTemplateParam) {
        Integer id = bizGatewayConfigTemplateParam.getId();
        Integer status = bizGatewayConfigTemplateParam.getStatus();
        // 更新枚举，更新只能更新未删除状态的
        LambdaUpdateWrapper<BizGatewayConfigTemplate> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper
                .eq(BizGatewayConfigTemplate::getId, id)
                .set(BizGatewayConfigTemplate::getStatus, status);
        boolean update = this.update(updateWrapper);
        if (!update) {
            throw new ServiceException(StatusExceptionEnum.UPDATE_STATUS_ERROR);
        }
    }

    /**
     * 校验参数，检查是否存在重复的编码等
     *
     * @author ssy
     * @since 2022/10/31 15:31
     */
    private void checkParam(BizGatewayConfigTemplateParam bizGatewayConfigTemplateParam, boolean isExcludeSelf) {
        Integer id = bizGatewayConfigTemplateParam.getId();
        String code = bizGatewayConfigTemplateParam.getCode();
        // 构建带code的查询条件
        LambdaQueryWrapper<BizGatewayConfigTemplate> queryWrapperByCode = new LambdaQueryWrapper<>();
        queryWrapperByCode.eq(BizGatewayConfigTemplate::getCode, code);
        // 如果排除自己，则增加查询条件主键id不等于本条id
        if (isExcludeSelf) {
            queryWrapperByCode.ne(BizGatewayConfigTemplate::getId, id);
        }
        // 查询重复记录的数量
        int countByCode = this.count(queryWrapperByCode);
        // 如果存在重复的记录，抛出异常，直接返回前端
        if (countByCode >= 1) {
            throw new ServiceException(500, "该编码已存在");
        }
    }

    /**
     * 获取网关配置模板
     *
     * @author ssy
     * @since 2022/10/31 15:31
     */
    private BizGatewayConfigTemplate queryBizGatewayConfigTemplate(BizGatewayConfigTemplateParam bizGatewayConfigTemplateParam) {
        return this.getById(bizGatewayConfigTemplateParam.getId());
    }

    /**
     * 返回系统字典类型参数树
     * @return
     */
    @Override
    public List<DirectoryTreeParam> tree() {
        final SysDictTypeParam sysDictTypeParam = new SysDictTypeParam();
        sysDictTypeParam.setCode("gateway_config_scene");
        final List<Dict> dicts = sysDictTypeService.dropDown(sysDictTypeParam);
        DirectoryTreeParam treeParam = new DirectoryTreeParam();
        treeParam.setId("000");
        treeParam.setTitle("全部场景");
        treeParam.setDisabled(true);
        treeParam.setKey("0-0");
        List<DirectoryTreeParam> treeParamList = new ArrayList<>();
        for (int i = 0; i < dicts.size(); i++) {
            DirectoryTreeParam treeParam1 = new DirectoryTreeParam();
            treeParam1.setId(dicts.get(i).get("code").toString());
            treeParam1.setTitle(dicts.get(i).get("value").toString());
            treeParam1.setDisabled(false);
            treeParam1.setKey(dicts.get(i).get("code").toString());
            treeParamList.add(treeParam1);
        }
        treeParam.setChildren(treeParamList);
        List<DirectoryTreeParam> treeParamList1 = new ArrayList<>();
        treeParamList1.add(treeParam);
        return treeParamList1;
    }
}
